package org.Yiran.timetale_re.event;

import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.server.ServerStoppingEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.Yiran.timetale_re.Timetale_re;
import org.Yiran.timetale_re.item.tool.hammer.base.HammerItem;
import org.Yiran.timetale_re.recipe.AnvilForgeRecipe;
import org.Yiran.timetale_re.recipe.ModRecipes;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 锤子与铁砧交互事件处理器
 * <p>
 * 处理玩家使用锤子在铁砧上将铁锭转换为铁板的逻辑
 * </p>
 */
@Mod.EventBusSubscriber(modid = Timetale_re.MODID)
public class HammerAnvilEventHandler {
    
    // 正在锻造的进程映射表，记录锻造开始时间和目标实体
    private static final Map<ForgeIdentifier, ForgeProcess> activeForges = new ConcurrentHashMap<>();
    
    // 玩家参与的锻造映射表，记录玩家当前在各个铁砧上参与的锻造
    // 用于支持玩家在不同铁砧上同时进行锻造
    private static final Map<UUID, Map<ForgeIdentifier, PlayerParticipation>> playerForges = new ConcurrentHashMap<>();
    
    // 挥动动画持续时间（毫秒）- 用于计算挥动间隔
    private static final long SWING_COOLDOWN = 250; // 挥动冷却时间
    
    // 2人合作时的速度加成
    private static final double TWO_PLAYER_SPEED_BONUS = 0.8;
    
    // 单个玩家最多同时参与的锻造过程数量
    private static final int MAX_CONCURRENT_FORGES_PER_PLAYER = 5;

    /**
     * 锻造标识符，用于唯一标识一次锻造过程（基于铁砧位置和目标实体）
     * 使用记录类（record）以减少样板代码并提高性能
     */
    private record ForgeIdentifier(BlockPos anvilPos, int entityID) {

    }
    
    /**
     * 玩家参与信息
     * 记录玩家参与锻造过程的相关时间信息
     */
    private static class PlayerParticipation {
        long joinTime;      // 加入时间
        long lastSwingTime; // 上次挥动时间
        long effectiveTime; // 有效参与时间
        boolean isSwinging; // 是否正在挥动
        
        /**
         * 构造函数，初始化玩家参与信息
         * @param currentTime 当前时间
         */
        PlayerParticipation(long currentTime) {
            this.joinTime = currentTime;
            this.lastSwingTime = currentTime - SWING_COOLDOWN; // 初始时允许立即挥动
            this.effectiveTime = 0;
            this.isSwinging = false;
        }
        
        /**
         * 检查玩家是否可以进行挥动
         * @param currentTime 当前时间
         * @return 是否可以挥动
         */
        boolean canSwing(long currentTime) {
            return currentTime - lastSwingTime >= SWING_COOLDOWN && !isSwinging;
        }
        
        /**
         * 开始挥动
         * @param currentTime 当前时间
         */
        void startSwing(long currentTime) {
            this.lastSwingTime = currentTime;
            this.isSwinging = true;
        }
        
        /**
         * 结束挥动并更新有效时间
         */
        void finishSwing() {
            this.isSwinging = false;
            this.effectiveTime += SWING_COOLDOWN;
        }
    }

    /**
     * 锻造过程数据类
     * 封装了单个锻造过程的所有相关信息
     */
    private static class ForgeProcess {
        final long startTime;           // 锻造开始时间
        final ItemEntity targetEntity;  // 目标物品实体
        final BlockPos anvilPos;        // 铁砧位置
        final Set<UUID> participants;   // 参与锻造的玩家UUID集合
        final AnvilForgeRecipe recipe;  // 锻造配方
        long lastSwingTime;             // 上次挥动时间
        int totalSwings;                // 总挥动次数
        
        /**
         * 构造函数，初始化锻造过程
         * @param startTime 锻造开始时间
         * @param targetEntity 目标物品实体
         * @param anvilPos 铁砧位置
         * @param recipe 锻造配方
         */
        ForgeProcess(long startTime, ItemEntity targetEntity, BlockPos anvilPos, AnvilForgeRecipe recipe) {
            this.startTime = startTime;
            this.targetEntity = targetEntity;
            this.anvilPos = anvilPos;
            this.recipe = recipe;
            // 使用线程安全的集合存储参与者
            this.participants = ConcurrentHashMap.newKeySet();
            this.lastSwingTime = startTime;
            this.totalSwings = 0;
        }
        
        /**
         * 计算多人锻造的加成系数
         * 根据参与玩家数量计算锻造速度加成
         * @return 锻造时间缩减系数
         */
        double getSpeedMultiplier() {
            int participantCount = participants.size();
            return switch (participantCount) {
                case 1 -> 1.0; // 单人无加成
                case 2 -> 1.0 + TWO_PLAYER_SPEED_BONUS; // 2人加成0.8
                default ->
                    // 3人及以上使用递减公式: 1.8 + 0.3*(n-2)
                    // 即3人时加成1.1(总共2.9倍), 4人时加成1.4(总共3.2倍)
                        1.0 + TWO_PLAYER_SPEED_BONUS + 0.3 * (participantCount - 2);
            };
        }
        
        /**
         * 获取调整后的锻造时间
         * 根据参与玩家数量计算实际需要的有效参与时间
         * @return 实际锻造时间（毫秒）
         */
        long getAdjustedDuration() {
            return (long) (recipe.forgeTime() / getSpeedMultiplier());
        }
        
        /**
         * 检查锤子是否满足配方要求
         * 验证锤子的挖掘等级是否满足配方要求
         * @param hammerItem 锤子物品
         * @return 是否满足要求
         */
        @SuppressWarnings("deprecation")
        boolean isHammerSufficient(ItemStack hammerItem) {
            if (hammerItem.getItem() instanceof HammerItem hammer) {
                // 使用工具的挖掘等级而不是锤子等级
                return hammer.getTier().getLevel() >= recipe.hammerLevel();
            }
            return false;
        }
        
        /**
         * 获取玩家的有效参与时间
         * 计算指定玩家在该锻造过程中的有效参与时间
         * @param playerId 玩家ID
         * @return 玩家有效参与时间（毫秒）
         */
        long getPlayerEffectiveTime(UUID playerId) {
            // 检查玩家是否参与了该锻造过程
            if (playerForges.containsKey(playerId)) {
                Map<ForgeIdentifier, PlayerParticipation> playerProcesses = playerForges.get(playerId);
                ForgeIdentifier forgeId = new ForgeIdentifier(anvilPos, targetEntity.getId());
                // 检查玩家在该铁砧上是否有参与记录
                if (playerProcesses.containsKey(forgeId)) {
                    return playerProcesses.get(forgeId).effectiveTime;
                }
            }
            return 0;
        }
    }

    /**
     * 处理玩家右键方块事件
     * 当玩家手持锤子并按下Shift键右键点击铁砧时，检查铁砧上方是否有铁锭掉落物
     * 如果有，则进行锻造过程
     *
     * @param event 玩家右键方块事件
     */
    @SubscribeEvent
    public static void onPlayerRightClickBlock(PlayerInteractEvent.RightClickBlock event) {
        // 检查是否为服务端，客户端不需要处理逻辑
        if (event.getLevel().isClientSide()) {
            return;
        }

        // 验证基本条件（潜行+锤子+铁砧）
        if (!isValidForgeAttempt(event)) {
            return;
        }

        // 获取相关参数
        Player player = event.getEntity();
        BlockPos pos = event.getPos();
        Level level = event.getLevel();
        
        // 查找铁砧上方的实体
        List<Entity> entities = getEntitiesAboveAnvil(level, pos);
        
        // 处理锻造逻辑
        handleForgeProcess(event, player, pos, level, entities);
    }
    
    /**
     * 服务器停止事件，清理所有锻造过程
     * 防止服务器重启时出现内存泄漏
     * 
     * @param event 服务器停止事件
     */
    @SubscribeEvent
    public static void onServerStopping(ServerStoppingEvent event) {
        // 清理所有锻造过程，释放内存
        activeForges.clear();
        playerForges.clear();
    }
    
    /**
     * 验证锻造尝试的基本条件
     * 检查玩家是否满足进行锻造的基本条件
     * 
     * @param event 玩家交互事件
     * @return 是否满足基本条件
     */
    private static boolean isValidForgeAttempt(PlayerInteractEvent.RightClickBlock event) {
        // 检查玩家是否按下Shift键
        if (!event.getEntity().isShiftKeyDown()) {
            return false;
        }

        // 检查玩家是否手持锤子
        if (!(event.getItemStack().getItem() instanceof HammerItem)) {
            return false;
        }

        // 检查点击的方块是否为铁砧
        BlockState blockState = event.getLevel().getBlockState(event.getPos());
        return blockState.is(Blocks.ANVIL) || blockState.is(Blocks.CHIPPED_ANVIL) || blockState.is(Blocks.DAMAGED_ANVIL);
    }
    
    /**
     * 获取铁砧上方的实体列表
     * 在铁砧正上方的一个方块空间内查找所有实体
     * 
     * @param level 世界对象
     * @param anvilPos 铁砧位置
     * @return 实体列表
     */
    private static List<Entity> getEntitiesAboveAnvil(Level level, BlockPos anvilPos) {
        // 计算铁砧上方位置
        BlockPos abovePos = anvilPos.above();
        // 创建检测区域包围盒
        AABB detectionBox = new AABB(abovePos);
        // 查找该区域内的所有实体
        return level.getEntitiesOfClass(Entity.class, detectionBox);
    }
    
    /**
     * 处理锻造过程
     * 主要的锻造逻辑处理方法，协调整个锻造过程
     * 
     * @param event 玩家交互事件
     * @param player 玩家
     * @param pos 铁砧位置
     * @param level 世界对象
     * @param entities 铁砧上方的实体列表
     */
    private static void handleForgeProcess(PlayerInteractEvent.RightClickBlock event, Player player, 
                                         BlockPos pos, Level level, List<Entity> entities) {
        // 获取玩家ID和当前时间
        UUID playerId = player.getUUID();
        long currentTime = System.currentTimeMillis();
        ItemStack heldItem = event.getItemStack();
        
        // 获取配方管理器
        RecipeManager recipeManager = level.getRecipeManager();
        
        // 查找当前铁砧上是否已有正在进行的锻造
        ForgeProcessContext context = findExistingForgeProcess(entities, pos, recipeManager);
        
        // 清理无效的锻造过程
        cleanupInvalidForges();
        
        // 检查玩家是否参与了过多的锻造过程
        if (isPlayerOverForgeLimit(playerId, context.forgeId)) {
            return;
        }
        
        // 处理已存在的锻造过程或创建新的锻造过程
        if (context.existingProcess != null) {
            handleExistingForgeProcess(event, player, pos, level, currentTime, 
                                     context.existingProcess, context.forgeId, playerId, heldItem);
        } else {
            startNewForgeProcess(event, player, pos, level, currentTime, entities, playerId, recipeManager, heldItem);
        }
    }
    
    /**
     * 锻造过程上下文，用于封装查找现有锻造过程的结果
     */
    private static class ForgeProcessContext {
        final ForgeProcess existingProcess; // 已存在的锻造过程
        final ForgeIdentifier forgeId;      // 锻造标识符
        
        /**
         * 构造函数
         * @param existingProcess 已存在的锻造过程
         * @param forgeId 锻造标识符
         */
        ForgeProcessContext(ForgeProcess existingProcess, ForgeIdentifier forgeId) {
            this.existingProcess = existingProcess;
            this.forgeId = forgeId;
        }
    }
    
    /**
     * 查找已存在的锻造过程
     * 在指定实体中查找匹配的锻造配方和已存在的锻造过程
     * 
     * @param entities 实体列表
     * @param pos 铁砧位置
     * @param recipeManager 配方管理器
     * @return 锻造过程上下文
     */
    private static ForgeProcessContext findExistingForgeProcess(List<Entity> entities, BlockPos pos, RecipeManager recipeManager) {
        ForgeProcess existingProcess = null;
        ForgeIdentifier forgeId = null;
        
        // 遍历实体列表查找匹配的锻造过程
        for (Entity entity : entities) {
            if (entity instanceof ItemEntity itemEntity) {
                ItemStack itemStack = itemEntity.getItem();
                // 查找匹配的配方
                AnvilForgeRecipe recipe = findMatchingRecipe(recipeManager, itemStack);
                if (recipe != null) {
                    // 构造锻造标识符
                    ForgeIdentifier id = new ForgeIdentifier(pos, entity.getId());
                    // 检查是否已存在该锻造过程
                    if (activeForges.containsKey(id)) {
                        existingProcess = activeForges.get(id);
                        forgeId = id;
                        break;
                    }
                }
            }
        }
        
        return new ForgeProcessContext(existingProcess, forgeId);
    }
    
    /**
     * 检查玩家是否超出锻造过程数量限制
     * 防止单个玩家同时参与过多锻造过程
     * 
     * @param playerId 玩家ID
     * @param forgeId 锻造标识符
     * @return 是否超出限制
     */
    private static boolean isPlayerOverForgeLimit(UUID playerId, ForgeIdentifier forgeId) {
        // 检查玩家是否参与了过多的锻造过程
        if (playerForges.containsKey(playerId) && 
            playerForges.get(playerId).size() >= MAX_CONCURRENT_FORGES_PER_PLAYER) {
            // 如果玩家已经参与了过多的锻造过程，不允许参与新的（除非是已参与的）
            return forgeId == null || !playerForges.get(playerId).containsKey(forgeId);
        }
        return false;
    }
    
    /**
     * 清理无效的锻造过程
     * 移除已经失效的锻造过程（如目标物品已被拾取或销毁）
     */
    private static void cleanupInvalidForges() {
        // 使用迭代器安全地移除元素
        Iterator<Map.Entry<ForgeIdentifier, ForgeProcess>> iterator = activeForges.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<ForgeIdentifier, ForgeProcess> entry = iterator.next();
            ForgeProcess process = entry.getValue();
            
            // 检查目标实体是否仍然存在且有效
            if (process.targetEntity.isRemoved() || 
                !process.recipe.matchesInput(process.targetEntity.getItem())) {
                // 清理无效的锻造过程
                cleanupForgeProcess(entry.getKey(), process);
                iterator.remove();
            }
        }
    }
    
    /**
     * 清理锻造过程相关的所有数据
     * 从所有相关数据结构中移除指定锻造过程的信息
     * 
     * @param forgeId 锻造标识符
     * @param process 锻造过程
     */
    private static void cleanupForgeProcess(ForgeIdentifier forgeId, ForgeProcess process) {
        // 遍历所有参与者，从他们的参与记录中移除该锻造过程
        for (UUID participantId : process.participants) {
            // 从玩家的锻造映射中移除
            if (playerForges.containsKey(participantId)) {
                playerForges.get(participantId).remove(forgeId);
                // 如果玩家没有任何锻造过程，移除其条目以节省内存
                if (playerForges.get(participantId).isEmpty()) {
                    playerForges.remove(participantId);
                }
            }
        }
    }
    
    /**
     * 查找匹配的锻造配方
     * 在所有可用的锻造配方中查找与输入物品匹配的配方
     * 
     * @param recipeManager 配方管理器
     * @param input 输入物品
     * @return 匹配的配方，如果找不到则返回null
     */
    private static AnvilForgeRecipe findMatchingRecipe(RecipeManager recipeManager, ItemStack input) {
        // 遍历所有可用的锻造配方
        for (AnvilForgeRecipe recipe : recipeManager.getAllRecipesFor(ModRecipes.ANVIL_FORGE_RECIPE_TYPE.get())) {
            // 检查输入物品是否匹配配方要求
            if (recipe.matchesInput(input)) {
                return recipe;
            }
        }
        return null;
    }
    
    /**
     * 处理已存在的锻造过程
     * 当玩家尝试参与一个已存在的锻造过程时调用此方法
     * 
     * @param event 玩家交互事件
     * @param player 玩家
     * @param pos 铁砧位置
     * @param level 世界对象
     * @param currentTime 当前时间
     * @param process 锻造过程
     * @param forgeId 锻造标识符
     * @param playerId 玩家ID
     * @param heldItem 手持物品
     */
    private static void handleExistingForgeProcess(PlayerInteractEvent.RightClickBlock event, Player player, 
                                                  BlockPos pos, Level level, long currentTime,
                                                  ForgeProcess process, ForgeIdentifier forgeId, UUID playerId, ItemStack heldItem) {
        // 检查锤子是否满足要求
        if (!process.isHammerSufficient(heldItem)) {
            return;
        }
        
        // 检查目标实体是否仍然存在且为有效的输入材料
        if (process.targetEntity.isRemoved() || 
            !process.recipe.matchesInput(process.targetEntity.getItem())) {
            // 目标已失效，取消锻造过程
            activeForges.remove(forgeId);
            cleanupForgeProcess(forgeId, process);
            return;
        }
        
        // 检查玩家是否可以挥动
        if (!canPlayerSwing(playerId, forgeId, currentTime)) {
            return;
        }
        
        // 处理玩家参与锻造过程
        handlePlayerParticipation(process, forgeId, playerId, currentTime);
        
        // 更新挥动状态
        process.lastSwingTime = currentTime;
        process.totalSwings++;
        
        // 检查是否完成锻造（基于所有参与玩家的有效时间）
        long effectiveTime = calculateTotalEffectiveTime(process);
        
        if (effectiveTime >= process.getAdjustedDuration()) {
            completeForgeProcess(level, pos, process, forgeId);
        }
        
        // 执行挥动操作
        performSwingAction(event, player, pos, level, process.totalSwings);
    }
    
    /**
     * 检查玩家是否可以挥动
     * @param playerId 玩家ID
     * @param forgeId 锻造标识符
     * @param currentTime 当前时间
     * @return 是否可以挥动
     */
    private static boolean canPlayerSwing(UUID playerId, ForgeIdentifier forgeId, long currentTime) {
        if (playerForges.containsKey(playerId) && playerForges.get(playerId).containsKey(forgeId)) {
            PlayerParticipation participation = playerForges.get(playerId).get(forgeId);
            return participation.canSwing(currentTime);
        }
        return true; // 如果没有找到参与记录，默认允许挥动
    }
    
    /**
     * 处理玩家参与锻造过程
     * 管理玩家加入锻造过程或更新其参与状态
     * 
     * @param process 锻造过程
     * @param forgeId 锻造标识符
     * @param playerId 玩家ID
     * @param currentTime 当前时间
     */
    private static void handlePlayerParticipation(ForgeProcess process, ForgeIdentifier forgeId, UUID playerId, long currentTime) {
        // 检查玩家是否已参与该锻造过程
        if (!process.participants.contains(playerId)) {
            // 玩家首次加入锻造过程
            process.participants.add(playerId);
            // 添加到玩家的锻造映射中
            playerForges.computeIfAbsent(playerId, k -> new ConcurrentHashMap<>()).put(forgeId, new PlayerParticipation(currentTime));
        } else {
            // 玩家已在锻造过程中，更新其参与状态
            updatePlayerParticipation(playerId, forgeId, currentTime);
        }
    }
    
    /**
     * 更新玩家参与状态
     * 更新已在锻造过程中的玩家的参与信息
     * 
     * @param playerId 玩家ID
     * @param forgeId 锻造标识符
     * @param currentTime 当前时间
     */
    private static void updatePlayerParticipation(UUID playerId, ForgeIdentifier forgeId, long currentTime) {
        // 检查玩家是否在该铁砧上有参与记录
        if (playerForges.containsKey(playerId) && playerForges.get(playerId).containsKey(forgeId)) {
            PlayerParticipation participation = playerForges.get(playerId).get(forgeId);
            // 检查玩家是否可以进行下一次挥动
            if (participation.canSwing(currentTime)) {
                // 开始挥动
                participation.startSwing(currentTime);
                
                // 设置定时器，在挥动完成后更新有效时间
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        participation.finishSwing();
                    }
                }, SWING_COOLDOWN);
            }
        }
    }
    
    /**
     * 计算所有参与玩家的总有效时间
     * 用于判断锻造过程是否完成
     * 
     * @param process 锻造过程
     * @return 所有参与玩家的总有效时间
     */
    private static long calculateTotalEffectiveTime(ForgeProcess process) {
        long effectiveTime = 0;
        // 累加所有参与玩家的有效时间
        for (UUID participantId : process.participants) {
            effectiveTime += process.getPlayerEffectiveTime(participantId);
        }
        return effectiveTime;
    }
    
    /**
     * 开始新的锻造过程
     * 当玩家在铁砧上开始一个新的锻造过程时调用此方法
     * 
     * @param event 玩家交互事件
     * @param player 玩家
     * @param pos 铁砧位置
     * @param level 世界对象
     * @param currentTime 当前时间
     * @param entities 铁砧上方的实体列表
     * @param playerId 玩家ID
     * @param recipeManager 配方管理器
     * @param heldItem 手持物品
     */
    @SuppressWarnings("deprecation")
    private static void startNewForgeProcess(PlayerInteractEvent.RightClickBlock event, Player player, 
                                            BlockPos pos, Level level, long currentTime,
                                            List<Entity> entities, UUID playerId, RecipeManager recipeManager, ItemStack heldItem) {
        // 查找并开始新的锻造过程
        for (Entity entity : entities) {
            if (entity instanceof ItemEntity itemEntity) {
                ItemStack itemStack = itemEntity.getItem();
                // 查找匹配的配方
                AnvilForgeRecipe recipe = findMatchingRecipe(recipeManager, itemStack);
                if (recipe != null) {
                    // 检查锤子是否满足要求
                    if (!(heldItem.getItem() instanceof HammerItem hammer) || hammer.getTier().getLevel() < recipe.hammerLevel()) {
                        continue; // 锤子等级不够，跳过此配方
                    }
                    
                    // 创建新的锻造过程
                    ForgeIdentifier id = new ForgeIdentifier(pos, entity.getId());
                    ForgeProcess process = new ForgeProcess(currentTime, itemEntity, pos, recipe);
                    
                    // 玩家加入锻造过程
                    process.participants.add(playerId);
                    // 添加到玩家的锻造映射中
                    playerForges.computeIfAbsent(playerId, k -> new ConcurrentHashMap<>()).put(id, new PlayerParticipation(currentTime));
                    activeForges.put(id, process);
                    
                    // 更新挥动状态
                    process.lastSwingTime = currentTime;
                    process.totalSwings++;
                    
                    // 处理玩家参与锻造过程
                    handlePlayerParticipation(process, id, playerId, currentTime);
                    
                    // 执行挥动操作
                    performSwingAction(event, player, pos, level, process.totalSwings);
                    
                    // 只处理一个物品
                    break;
                }
            }
        }
    }
    
    /**
     * 完成锻造过程
     * 当锻造时间满足要求时调用此方法完成锻造
     * 
     * @param level 世界对象
     * @param pos 铁砧位置
     * @param process 锻造过程
     * @param forgeId 锻造标识符
     */
    private static void completeForgeProcess(Level level, BlockPos pos, ForgeProcess process, ForgeIdentifier forgeId) {
        // 完成锻造
        ItemStack itemStack = process.targetEntity.getItem();
        
        // 消耗输入材料
        if (itemStack.getCount() > process.recipe.inputCount()) {
            itemStack.shrink(process.recipe.inputCount());
            process.targetEntity.setItem(itemStack); // 更新物品堆
        } else {
            process.targetEntity.discard(); // 移除物品实体
        }
        
        // 创建输出物品
        ItemStack output = process.recipe.getResultItem(level.registryAccess()).copy();
        
        // 创建新的物品实体
        ItemEntity outputEntity = new ItemEntity(
                level,
                process.targetEntity.getX(),
                process.targetEntity.getY(),
                process.targetEntity.getZ(),
                output
        );
        
        // 添加一些随机运动
        outputEntity.setDeltaMovement(
                (level.random.nextDouble() - 0.5) * 0.1,
                0.2,
                (level.random.nextDouble() - 0.5) * 0.1
        );
        
        // 添加到世界
        level.addFreshEntity(outputEntity);
        
        // 播放完成音效
        level.playSound(null, pos, SoundEvents.ANVIL_USE, SoundSource.BLOCKS, 0.8f, level.random.nextFloat() * 0.1f + 0.9f);
        
        // 清理锻造状态
        activeForges.remove(forgeId);
        cleanupForgeProcess(forgeId, process);
    }
    
    /**
     * 执行挥动操作
     * 处理玩家挥动锤子的视觉和听觉反馈
     * 
     * @param event 玩家交互事件
     * @param player 玩家
     * @param pos 铁砧位置
     * @param level 世界对象
     * @param swingCount 挥动次数
     */
    private static void performSwingAction(PlayerInteractEvent.RightClickBlock event, Player player, 
                                          BlockPos pos, Level level, int swingCount) {
        ItemStack heldItem = event.getItemStack();
        
        // 损坏锤子
        heldItem.hurtAndBreak(1, player, (p) -> 
            p.broadcastBreakEvent(event.getHand())
        );
        
        // 根据总挥动次数调整音调，增加节奏感
        float pitch = 0.8f + (swingCount % 4) * 0.05f;
        
        // 播放锻造音效
        level.playSound(null, pos, SoundEvents.ANVIL_PLACE, SoundSource.BLOCKS, 0.5f, pitch);
        
        // 播放挥手动作
        if (player instanceof ServerPlayer) {
            // 在服务端触发客户端的挥动动画
            player.swing(event.getHand(), true);
        } else {
            player.swing(event.getHand());
        }
    }
}